package com.tnxst.phexamination.utils;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;


import com.google.gson.internal.LinkedTreeMap;
import com.tnxst.phexamination.constant.HISConfig;



import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.impl.llom.OMSerializableImpl;
import org.apache.axiom.om.impl.llom.OMTextImpl;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.transport.http.HTTPConstants;


import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * WebService连接工具
 */
public class WebServiceUtils {

    // 线程池的大小
    private static int threadSize = 5;
    // 创建一个可重用固定线程数的线程池，以共享的无界队列方式来运行这些线程
    private static ExecutorService threadPool = Executors.newFixedThreadPool(threadSize);
    // 连接响应标示
    public static final int SUCCESS_FLAG = 0;
    public static final int ERROR_FLAG = 1;

    /**
     * 调用WebService接口，此方法只访问过用Java写的服务器
     *
     * @param endPoint        WebService服务器地址
     * @param nameSpace       命名空间
     * @param methodName      WebService的调用方法名
     * @param mapParams       WebService的参数集合，可以为null
     * @param responseCallBack 服务器响应接口
     */
    public static void call(final String endPoint,
                            final String nameSpace,
                            final String soapAction,
                            final String methodName,
                            Map<String, String> mapParams,
                            final Response responseCallBack) {
        final Handler responseHandler = new Handler() {

            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
//                ConcurrentHashMap map = new ConcurrentHashMap();
//                map.put("","");
//                map.get("");
//                map.size();

                // 根据消息的arg1值判断调用哪个接口
                if (msg.arg1 == SUCCESS_FLAG){
                    Object data = msg.obj;
                    Map<String, Object> response = GsonUtils.gsonToMaps(data.toString());
                    if (response == null || response.get("Result") == null){
                        String json = data.toString();
                        json = StringUtils.replace(json);
                        response = GsonUtils.gsonToMaps(json);
                        if (response == null  || response.get("Result") == null)
                            return;
                    }
                    Integer result = Double.valueOf(response.get("Result").toString()).intValue();
                    if (result == 1){
                        Object o = response.get("Msg");
                        if (o instanceof List){
                            ArrayList<Object> list = (ArrayList) o;
                            responseCallBack.onSuccess(list);
                            return;
                        }

                        if (o instanceof Map){
                            LinkedTreeMap<String,Object> r = (LinkedTreeMap<String, Object>) o;
                            responseCallBack.onSuccess(r);
                            return;
                        }
                        responseCallBack.onSuccess(response);


                    }else if (result == 0){
                        String r = response.get("Msg").toString();
                        responseCallBack.onError(r);
                    }
                } else{
                    responseCallBack.onError(msg.obj.toString());
                }

            }

        };

            // 提交一个子线程到线程池并在此线种内调用WebService
            if (threadPool == null || threadPool.isShutdown())
                threadPool = Executors.newFixedThreadPool(threadSize);
            threadPool.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        final ServiceClient serviceClient = new ServiceClient();
                        //创建服务地址WebService的URL,注意不是WSDL的URL
                        EndpointReference targetEPR = new EndpointReference(endPoint);
                        Options options = serviceClient.getOptions();
                        options.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, true);
                        options.setManageSession(true);
                        options.setTo(targetEPR);
                        //确定调用方法（wsdl 命名空间地址 (wsdl文档中的targetNamespace) 和 方法名称 的组合）
                        options.setAction(soapAction);

                        OMFactory fac = OMAbstractFactory.getOMFactory();
                        OMNamespace omNs = fac.createOMNamespace(nameSpace, "");
                        // 指定方法
                        OMElement method = fac.createOMElement(methodName, omNs);
                        for (Map.Entry<String, String> en : mapParams.entrySet()) {
                            String mname = en.getKey();
                            String value = en.getValue();
                            // 指定方法的参数
                            OMElement mobileCode = fac.createOMElement(mname, omNs);
                            mobileCode.setText(value); // 在这里输入需要上传的参数
                            method.addChild(mobileCode);
                        }
                        OMElement userID = fac.createOMElement("userID", omNs);
                        userID.setText("");
                        method.addChild(userID);
                        method.build();
                        String res = "";
                        // 解决EOFException
                        System.setProperty("http.keepAlive", "false");
                        //远程调用web服务
                        OMElement result = serviceClient.sendReceive(method);
                        Iterator it = result.getChildren();
                        while (it.hasNext()) {
                            Object next = it.next();
                            if (next instanceof OMTextImpl) {
                                OMTextImpl reportElement = (OMTextImpl) next;
                                res += reportElement.getText();
                            } else if (next instanceof OMElement) {
                                OMElement reportElement = (OMElement) next;
                                res += reportElement.getText();
                            } else {
                                OMSerializableImpl reportElement = (OMSerializableImpl) it.next();
                                res += reportElement;
                            }
                        }
                        serviceClient.cleanupTransport();
                        // 将获取的消息利用Handler发送到主线程
                        res = StringUtils.replace(res);
                        responseHandler.sendMessage(responseHandler.obtainMessage(0, SUCCESS_FLAG, 0, res));
                    } catch (Exception e) {
                        String error = e.getMessage();
                        responseHandler.sendMessage(responseHandler.obtainMessage(0, ERROR_FLAG, 0, error));
                    }
                }
            });
    }

    public static void call(String trade,
                            Map<String,Object> data,
                            final Response response){
        call(trade,data,HISConfig.TEST,response);
    }

    public static void call(String trade,
                            Map<String,Object> data,
                            int test,
                            final Response response
                            ){
        LinkedHashMap<String, String> params = new LinkedHashMap<>();
        String json = StringUtils.replace(GsonUtils.toJson(data));
        params.put("TradeCode",trade);
        params.put("InputParameter",json);
        String endPoint;
        if (test == 1)
            endPoint = HISConfig.TEST_END_POINT;
        else
            endPoint = HISConfig.FORMAL_END_POINT;

        call(endPoint,HISConfig.NAME_SPACE,HISConfig.SOAP_ACTION,HISConfig.METHOD_NAME,params,response);
    }

    /**
     * 设置线程池的大小
     *
     * @param threadSize
     */
    public static void setThreadSize(int threadSize) {
        WebServiceUtils.threadSize = threadSize;
        threadPool.shutdownNow();
        threadPool = Executors.newFixedThreadPool(WebServiceUtils.threadSize);
    }

    /**
     * 服务器响应接口，在响应后需要回调此接口
     */
    public interface Response<T> {
        public void onSuccess(T result);

        public void onError(String error);
    }
}
